# 数据包序列生成器.py
'''
给定一个数据流集的长度序列, 则这一长度序列定义了一个数据流长度的分布. 
这里实现的数据包序列生成器可以根据这一分布生成任意长度的数据包序列.
2020年4月4日
'''
import numpy as np
import bisect
import time
import math
import random

class flow_packets_generator:
	def __init__(self, 数据流长度序列, 并发流数, 数据包数, 输出文件):
		self.并发流数 = 并发流数
		self.数据包数 = 数据包数
		self.最小流长度 = 最小流长度
		self.alpha = alpha
		self.输出文件 = 输出文件
		np.random.seed(0)
		random.seed(0)

		self.并发流 = dict()
		self.缓冲区 = []
		self.数据包序列 = []

		self.初始化()
		self.get_pkts_sequence()

	def 初始化(self):
		流长度分布 = np.floor((np.random.pareto(self.alpha, size=self.并发流数) + 1) * self.最小流长度).astype(int)
		for 流长度 in 流长度分布:
			assert(流长度 > 0)
			标识符 = self.get_rand_flowid()
			self.并发流[标识符] = 流长度
			for 甲 in range(流长度):
				self.缓冲区.append(标识符)
		random.shuffle(self.缓冲区)


	def get_pkts_sequence(self):
		with open(self.输出文件, 'w') as f:
			pass
		st_time = time.time()
		flag_time = st_time
		for i in range(self.数据包数):
			if i % 10000 == 9999:
				with open(self.输出文件, 'a') as f:
					f.write("\n".join(self.数据包序列) + "\n")
					self.数据包序列 = []
				time_now = time.time()
				print("进度报告:%d, 单位时间%.3f, 总时间:%.3f" % \
						(i,  time_now - st_time, time_now - flag_time))
				st_time = time_now
			标识符 = self.缓冲区[-1]
			self.数据包序列.append(标识符)
			del self.缓冲区[-1]
			self.并发流[标识符] -= 1
			if 0 == self.并发流[标识符]:
				del self.并发流[标识符]
				流长度 = int((np.random.pareto(self.alpha) + 1) * self.最小流长度)
				标识符 = self.get_rand_flowid()
				self.并发流[标识符] = 流长度
				for 甲 in range(流长度):
					self.缓冲区.append(标识符)
					临时长度 = len(self.缓冲区)
					索引 = random.randint(0, 临时长度 - 1)
					临时变量 = self.缓冲区[索引]
					self.缓冲区[索引] = self.缓冲区[-1]
					self.缓冲区[-1] = 临时变量
		if len(self.数据包序列) > 0:
			with open(self.输出文件, 'a') as f:
				f.write("\n".join(self.数据包序列))
				self.数据包序列 = []

	def get_rand_flowid(self):
		lst = []
		for i in range(8):
			item = random.randint(1, 256)
			lst.append(str(item))
		srcip = ".".join(lst[0:4])
		dstip = ".".join(lst[4:8])
		proto = random.randint(1, 2)
		if 1 == proto:
			proto = "6"
		elif 2 == proto:
			proto = "17"
		srcport = str(random.randint(1, 65536))
		dstport = str(random.randint(1, 65536))
		标识符 = "\t".join([srcip, dstip, proto, srcport, dstport])
		return 标识符


if __name__ == "__main__":
	flow_packets_generator(100, 100000, 1, 1.05, "./test.txt")
